package fi.solita.dojo.mazeserver.game.internal

import scala.collection._
import map._
import util._

object GameMap {
  def apply (locations: immutable.Map[Coordinates, GameLocation]) =
    new GameMap(locations)
}

class GameMap(val locations: immutable.Map[Coordinates, GameLocation]){

	lazy val height = calculateHeight()
	lazy val width = calculateWidth()

	def removePoint(c: Coordinates): GameMap = replace(c, GameLocation.corridor(c))
 
	def replace(c: Coordinates, loc: GameLocation): GameMap = {
	  val newMap = locations + (c -> loc) // update ((c, loc))
	  GameMap(newMap)
	}
 
	def apply(c: Coordinates): GameLocation = locations(c)

	def get(c: Coordinates) = locations.get(c)

	override def toString(): String = {
			val seq = for (i <- 0 until height) yield {
				val line = for (j <- 0 until width) yield
				get(Coordinates(i,j)) match {
				case Some(gl) => consoleMarker(gl)
				case None => 'X'
				}
				line.mkString("\"", "", "\"")
			}
			seq.toList.mkString(" ")
	}

	private def consoleMarker(loc: GameLocation): Char = {
			if (loc.passable) {
				if (loc.hole) 'u' else if (loc.point) '.' else '_'
			} else 'x'
	} 

	private def calculateHeight(): Int = {
			var max = 0;
			for ((l,_) <- locations){
				if (l.row > max) max = l.row
			}
			max + 1
	}

	private def calculateWidth(): Int = {
			var max = 0;
			for ((l,_) <- locations){
				if (l.column > max) max = l.column
			}
			max + 1
	}

	def randomCoordinates(): Coordinates = Coordinates(Util.randomPositiveInt(height), Util.randomPositiveInt(width))

	def randomPassableCoordinates(): Coordinates = {
			val c = randomCoordinates
			(apply(c).passable && !apply(c).hole) match {
			case true => c
			case false => randomPassableCoordinates
			}
	}
}

